package com.tanhua.sso.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.backmanage.service.LoginLogService;
import com.tanhua.backmanage.vo.LoginLogVoQs;
import com.tanhua.common.mapper.UserMapper;
import com.tanhua.common.pojo.User;
import com.tanhua.dubbo.server.api.HuanXinApi;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mobile.device.Device;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class UserService {

    /**
     * 1.redis
     * 2.mapper
     * 3.盐值(直接写死)
     */
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    //日志(邱嵩)
    private LoginLogService loginLogService;

    @Reference(version = "1.0.0")
    private HuanXinApi huanXinApi;

    String secret = "9876";

    /**
     * 1.判断验证码是否存在
     * 1.1存在,验证后删除
     * 1.2不存在,验证后直接结束
     * 2.判断用户是否存在
     * 2.1存在
     * 2.2不存在 ,创建新用户
     * 3.生成token(不管是新用户还是老用户,都需要生成token)
     * 4.返回token和用户状态
     *
     * @param phone
     * @param verificationCode
     * @return
     */
    public String login(String phone, String verificationCode ,Device device) {
        String redisKey = "CHECK_CODE_" + phone;
        boolean isNewUser = false;
        String flag = redisTemplate.opsForValue().get(redisKey);
        if (!StringUtils.equals(flag, verificationCode)) {
            return null;
        }

        //删除有效验证码
        redisTemplate.delete(redisKey);
        //判断是否是新用户
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("mobile", phone);
        User user = userMapper.selectOne(queryWrapper);



        if (user == null) {
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("123456"));
            userMapper.insert(user);
            isNewUser = true;

            //注册环信用户
            Boolean result = huanXinApi.register(user.getId());
            if (!result) {
                //注册环信失败，记录日志
                log.error("注册环信用户失败~ userId = " + user.getId());
            }
        }

        /*//根据userId检验是否存在冻结
        String key = "USER_FREEZE_RANGE_" +  user.getId();
        String freezeRange = redisTemplate.opsForValue().get(key);
        if (ObjectUtil.isNotEmpty(freezeRange) && freezeRange.equals("1")){
            return null;
        }*/

        //生成token
        Map<String, Object> claim = new HashMap<>();
        claim.put("id", user.getId());
        String token = Jwts.builder()
                .setClaims(claim)
                .signWith(SignatureAlgorithm.HS256, secret)
                .setExpiration(new DateTime().plusHours(12).toDate()) //设置过期时间，12小时后过期
                .compact();


        //日志记录登录信息
        LoginLogVoQs loginLogVoQs = new LoginLogVoQs();

        if (device.isMobile()) {
            System.out.println("========请求来源设备是手机！========");
            loginLogVoQs.setEquipment("手机");
        } else if (device.isTablet()) {
            System.out.println("========请求来源设备是平板！========");
            loginLogVoQs.setEquipment("平板");
        } else if(device.isNormal()){
            System.out.println("========请求来源设备是PC！========");
            loginLogVoQs.setEquipment("PC");
        }else {
            System.out.println("========请求来源设备是其它！========");
            loginLogVoQs.setEquipment("其他设备");
        }


        loginLogVoQs.setUserId(user.getId());
        loginLogService.save(loginLogVoQs);

        return token + "|" + isNewUser;
    }

    //校验token
    public User queryUserByToken(String token) {
        System.out.println("校验处token:" + token);
        try {
            // 通过token解析数据
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(secret)//盐值要相同
                    .parseClaimsJws(token)
                    .getBody();
            User user = new User();
            user.setId(Long.valueOf(body.get("id").toString()));
            /**
             * 将手机号存到redis中的目的只有一个,尽量不要去关系型数据库中查找手机号
             */
            String redisKey = "TANHUA_USER_MOBILE_" + user.getId();
            Boolean result = redisTemplate.hasKey(redisKey);
            if (result) {
                //redis中有,就直接set
                user.setMobile(redisTemplate.opsForValue().get(redisKey));
            } else {
                //redis中没有,就到数据库中查找
                User user1 = userMapper.selectById(user.getId());
                user.setMobile(user1.getMobile());
                //找到了就存到redis中
                long timeout = Long.valueOf(body.get("exp").toString()) * 1000 - System.currentTimeMillis();
                redisTemplate.opsForValue().set(redisKey, user1.getMobile(), timeout, TimeUnit.MILLISECONDS);
            }
            return user;
        } catch (ExpiredJwtException e) {
            log.info("token已经过期！ token = " + token);
        } catch (Exception e) {
            log.error("token不合法！ token = " + token, e);
        }
        return null;
    }
}
